<?php declare(strict_types=1);
/**
 * @author      xianganyall <xianganyall@gmail.com>
 * @copyright   2023-2025 owner
 **/

namespace Srv\Scripts\Tools;

use Srv\Apps\Proto\Enum\LangKeyEnum;
use Srv\Libs\Boot;
use Srv\Libs\Common\CommFile;
use Srv\Libs\Tools\ReflectionClassData;
use Srv\Libs\Tools\ShellPrint;

require_once dirname(__DIR__, 2).'/Libs/Boot.php';
Boot::runConf('');

$langDirPath        = __DIR__.'/Lang/';
$langCsvFile        = __DIR__.'/Lang/lang.csv';
$langResultCsvFile  = __DIR__.'/Lang/langResult.csv';
$langKeyPadLength   = 44;
$langGenDefList     = ['zh', 'en'];
$csvHeadDefList     = [
    'KEY'           => 'langKey',       // val值固定不可更改
    '注释'           => 'langDesc',      // val值固定不可更改
    '提示'           => 'langTips',      // val值固定不可更改
    'English'       => 'en',
    '中文'           => 'zh',
];

// 读取CSV文件
function readCsvToLangList(string $filePath, array $csvHeadDefList):array
{
    $langDataList       = [];
    if(count($csvHeadDefList) < 1) return $langDataList;
    if(strlen($filePath) > 0 && file_exists($filePath) && $fileFp = fopen($filePath, 'r')){
        $isHeadLine     = true;
        $csvHeadDef     = [];
        while(!feof($fileFp)){
            $lineData           = fgetcsv($fileFp);
            if(!is_array($lineData) || count($lineData) < 3 || !isset($lineData[2])) break;
            if($isHeadLine){
                $isHeadLine     = false;
                foreach ($lineData as $lineIndex => $lineValue){
                    if($lineIndex === 0 && substr($lineValue, 0, 3) === chr(0xEF).chr(0xBB).chr(0xBF)) $lineValue = substr($lineValue, 3);  // 清除UTF-8的BOM头
                    $lineValue  = trim($lineValue);
                    if(strlen($lineValue) > 0 && isset($csvHeadDefList[$lineValue]) && is_string($csvHeadDefList[$lineValue]) && strlen($csvHeadDefList[$lineValue]) > 0){
                        $csvHeadDef[$lineIndex] = $csvHeadDefList[$lineValue];
                    }
                }
            }else{
                if(count($csvHeadDef) < 1) break;
                $langKeyLine    = '';
                $langKeyData    = [];
                foreach ($lineData as $lineIndex => $lineValue){
                    if(isset($csvHeadDef[$lineIndex])){
                        if($csvHeadDef[$lineIndex] === 'langKey') $langKeyLine = str_replace('.', '_', trim($lineValue));
                        $langKeyData[$csvHeadDef[$lineIndex]] = $lineValue;
                    }
                }
                if(strlen($langKeyLine) > 0 && count($langKeyData) > 0) $langDataList[$langKeyLine] = $langKeyData;
            }
        }
        fclose($fileFp);
    }
    return $langDataList;
}

// 写入CSV文件
function writeCsv(string $filePath, array $csvDataList, array $csvHeadDefList):bool
{
    if(count($csvHeadDefList) < 1) return false;
    $fileFp             = fopen($filePath, 'w+');
    if($fileFp){
        fwrite($fileFp, chr(0xEF).chr(0xBB).chr(0xBF));     // 写入UTF-8的BOM头,防止乱码
        $lineHeadDef    = [];
        $lineHeadIndex  = 0;
        $lineHeadData   = [];
        $lineTplData    = [];
        foreach ($csvHeadDefList as $csvHeadDefName => $csvHeadDefKey){
            $lineHeadDef[$csvHeadDefKey]    = $lineHeadIndex;
            $lineHeadData[$lineHeadIndex]   = $csvHeadDefName;
            $lineTplData[$lineHeadIndex]    = '';
            ++$lineHeadIndex;
        }
        fputcsv($fileFp, $lineHeadData);
        if(count($csvDataList) > 0) foreach ($csvDataList as $lineData){
            $lineDataResult                 = $lineTplData;
            foreach ($lineData as $lineKey => $lineValue){
                if(isset($lineHeadDef[$lineKey])) $lineDataResult[$lineHeadDef[$lineKey]] = $lineValue;
            }
            fputcsv($fileFp, $lineDataResult);
        }
        fclose($fileFp);
        return true;
    }else{
        return false;
    }
}

// 写入语言文件
function writeLangFile(string $filePath, array $langDataList, int $langKeyPadLength):bool
{
    $langFileHeader     = <<<EOFHEADER
<?php declare(strict_types=1);
/**
 * @author      xianganyall <xianganyall@gmail.com>
 * @copyright   2023-2025 owner
 **/
die('ERR');
?>
################################################################################

EOFHEADER;
    $fileFp             = fopen($filePath, 'w+');
    if($fileFp){
        fwrite($fileFp, $langFileHeader);
        $langFileContent        = '';
        if(count($langDataList) > 0) foreach ($langDataList as $langDataItem){
            $langKey            = strval($langDataItem['langKey']??'');
            $langValue          = strval($langDataItem['langValue']??'');
            $langFileContent    .= str_pad($langKey, $langKeyPadLength, ' ', STR_PAD_RIGHT).'= '.$langValue."\n";
        }
        fwrite($fileFp, $langFileContent);
        fclose($fileFp);
        return true;
    }else{
        return false;
    }
}
// 读取CSV语言文件
$langDataList       = readCsvToLangList($langCsvFile, $csvHeadDefList);
$langResultList     = [];
$refClassData       = ReflectionClassData::getRefDataByProto(LangKeyEnum::class);
if(isset($refClassData['constantList']) && count($refClassData['constantList']) > 0){
    foreach($refClassData['constantList'] as $propertyName => $propertySet){
        if(substr($propertyName, 0, 1) === '_' || !isset($propertySet['value']) || !is_numeric($propertySet['value'])) continue;
        $commentShow        = trim(str_replace('&#64;', '@', $propertySet['comment']));
        if(!isset($langDataList[$propertyName])) ShellPrint::printFailedString($propertyName.', '.$commentShow."\n");
        $langResultList[$propertyName] = array_merge($langDataList[$propertyName]??[], ['langKey' => $propertyName, 'langDesc' => $commentShow]);
        $langKeyPadLength   = max($langKeyPadLength, strlen($propertyName));
    }
}
// 生成CSV结果文件
if(!writeCsv($langResultCsvFile, $langResultList, $csvHeadDefList)){
    ShellPrint::printErrorString('Write Lang Result File: Fail, '.CommFile::getRelativePath($langResultCsvFile, __DIR__)."\n");
}else{
    ShellPrint::printSuccessString('Write Lang Result File: Success, '.CommFile::getRelativePath($langResultCsvFile, __DIR__)."\n");
}
// 生成语言文件
if(count($langGenDefList) > 0){
    foreach ($langGenDefList as $langGenKey){
        ShellPrint::printWarningString('gen Lang File: '.$langGenKey." ...\n");
        $langGenDataList        = [];
        foreach ($langResultList as $langResultItem){
            $langKey            = strval($langResultItem['langKey']??'');
            $langDesc           = strval($langResultItem['langDesc']??'');
            $langTips           = strval($langResultItem['langTips']??'');
            if(strlen($langKey) < 1) continue;
            if(!isset($langResultItem[$langGenKey])){
                $langValue      = '';
                $langFileLine   = str_pad($langKey, $langKeyPadLength, ' ', STR_PAD_RIGHT).'= '.$langValue."\n";
                ShellPrint::printFailedString($langFileLine);
            }else{
                $langValue      = preg_replace("/[\n\r]+/", '\n', $langResultItem[$langGenKey]);
            }
            $langGenDataList[$langKey] = ['langKey' => $langKey, 'langDesc' => $langDesc, 'langTips' => $langTips, 'langValue' => $langValue];
        }
        $langDataFile           = $langDirPath.$langGenKey.'.php';
        if(!writeLangFile($langDataFile, $langGenDataList, $langKeyPadLength)){
            ShellPrint::printErrorString('Gen Lang File: Fail, '.CommFile::getRelativePath($langDataFile, __DIR__)."\n");
        }else{
            ShellPrint::printSuccessString('Gen Lang File: Success, '.CommFile::getRelativePath($langDataFile, __DIR__)."\n");
        }
    }
}
